#include "stdafx.h"

#ifdef _DEBUG
	#undef THIS_FILE
	static char THIS_FILE[] = __FILE__;
	#define new DEBUG_NEW
#endif

UMYCOMMAND_API class UMyAnsCache _ansCache;
/////////////////////////////////////////////////////////////////////////////////////////////////
UMyAnsCache::UMyAnsCache(void):__item__(NULL)
{
	InitializeCriticalSection(&__cs__);
}

UMyAnsCache::~UMyAnsCache(void)
{
	UMyAnsCache::Release();
	DeleteCriticalSection(&__cs__);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
void UMyAnsCache::Release(void)
{
	PANS_ITEM pItem=NULL;
	EnterCriticalSection(&__cs__);
	for(;__item__;__item__=pItem)
	{
		pItem = __item__->pNext;
		zwl_memory_release((LPSTR&)__item__);
	}
	LeaveCriticalSection(&__cs__);
}

void UMyAnsCache::Register(DWORD req_ans_command,
							DWORD size_command,
							DWORD size_check,
							DWORD size_binded,
							LPCVOID buffer_check,
							LPCVOID buffer_binded,
							LPCVOID buffer_command)
{
	LPSTR lpMalloc=zwl_memory_malloc(sizeof(ANS_ITEM)+size_command+size_binded+size_check);
	if(lpMalloc)
	{
		PANS_ITEM pItem=(PANS_ITEM)lpMalloc;

		pItem->req_ans_command = req_ans_command;
		pItem->size_command = size_command;
		pItem->size_binded = size_binded;

		if(size_check) memcpy(pItem->buffer,buffer_check,size_check);
		if(size_binded) memcpy(pItem->buffer+size_check,buffer_binded,size_binded);
		memcpy(pItem->buffer+size_check+size_binded,buffer_command,size_command);

		EnterCriticalSection(&__cs__);
		pItem->pNext = __item__;
		__item__ = pItem;
		LeaveCriticalSection(&__cs__);
	}
}

LPVOID	UMyAnsCache::Read(DWORD	req_ans_command,
			DWORD size_command,
			DWORD size_check,
			DWORD size_binded,
			LPCVOID buffer_check,
			LPVOID buffer_binded)
{
	PANS_ITEM pItem=NULL;
	EnterCriticalSection(&__cs__);
	for(pItem=__item__;pItem;pItem=pItem->pNext)
	{
		if(pItem->req_ans_command==req_ans_command
			&&pItem->size_command==size_command
			&&pItem->size_check==size_check
			&&pItem->size_binded==size_binded)
		{
			if(size_check&&memcmp(pItem->buffer,buffer_check,size_check)) continue;
			if(size_binded) memcpy(buffer_binded,pItem->buffer+size_check,size_binded);
			return(pItem->buffer+size_check+size_binded);
		}
	}
	LeaveCriticalSection(&__cs__);
	return(NULL);
}

void UMyAnsCache::Reset(void)
{
	LeaveCriticalSection(&__cs__);
}
